using Microsoft.AspNetCore.Http.Json;
using Microsoft.AspNetCore.Identity;
using Quickly.Identity;
using Quickly.Identity.API;
using Quickly.Identity.Domain;
using Quickly.Identity.EntityFrameworkCore;
using System.Text.Json.Serialization;

var versions = new[] {
    new Version(1, 0),
    new Version(2, 0)
};

var builder = WebApplication.CreateBuilder(args);

builder.Configuration.AddEnvironmentVariables("QuickIdentityAPI_");

builder.Services.AddProblemDetails();
builder.Services.AddControllers().AddJsonOptions(options =>
{
    options.JsonSerializerOptions.PropertyNamingPolicy = System.Text.Json.JsonNamingPolicy.CamelCase;
});
builder.Services.Configure<JsonOptions>(options =>
{
    options.SerializerOptions.Converters.Add(new JsonStringEnumConverter());
});

builder.Services.AddIdentityDbContextQuickly<QuickIdentityDbContext>(builder.Configuration);
builder.Services.AddQuickIdentity()
    .AddEntityFrameworkStores<QuickIdentityDbContext>();

builder.Services.AddTransient<IEmailSender<AppUser>, EmptyEmailSender<AppUser>>();

builder.Services.AddEndpointsApiExplorer();
builder.Services.AddIdentityEndpointsVersioning();

foreach (var version in SupportApiVersions.Versions)
{
    builder.Services.AddOpenApiDocument(options =>
    {
        options.Title = "Quickly Identity API";

        options.DocumentName = "v" + version.MajorVersion;
        options.ApiGroupNames = new[] { "v" + version.MajorVersion };
        options.Version = version.MajorVersion + "." + version.MinorVersion;
        options.AllowNullableBodyParameters = true;
        options.PostProcess = document =>
        {
            var pattern = "{version:apiVersion}";
            foreach (var pair in document.Paths.ToArray())
            {
                document.Paths.Remove(pair.Key);

                document.Paths[pair.Key.Replace(pattern, version.MajorVersion.ToString())] = pair.Value;
            }
        };
    });
}

builder.Services.AddCors(options =>
{
    if (builder.Environment.IsDevelopment())
    {
        options.AddDefaultPolicy(policy =>
        {
            policy.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader();
        });
    }
    else
    {
        var allowedOrigins = new List<string>();
        builder.Configuration.GetSection("AllowedOrigins").Bind(allowedOrigins);
        options.AddDefaultPolicy(policy =>
        {
            policy.WithOrigins(allowedOrigins.ToArray()).AllowAnyMethod().AllowAnyHeader();
        });
    }
});

var app = builder.Build();

using (var scope = app.Services.CreateScope())
{
    var context = scope.ServiceProvider.GetRequiredService<QuickIdentityDbContext>();

    var created = context.Database.EnsureCreated();
}

app.UseCors();
app.UseStaticFiles();
app.UseHostFrontendIfConfigured();

app.UseAuthentication();
app.UseAuthorization();

app.MapIdentityApiQuickly();
app.MapIdentityManageApi();
app.MapQuickIdentityEndpoints();

if (app.Environment.IsDevelopment())
{
    app.UseOpenApi();
    app.UseSwaggerUi();
}

app.Run();
